package com.sie.zhq.module;

import android.util.Log;

import com.sie.tools.WltLib;
import com.sie.zhq.bean.IdentityInfo317Bean;
import com.sie.zhq.constconfig.ConstDefine;
import com.sie.zhq.tool.ByteTool;
import com.sie.zhq.tool.FileUnits;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;

/**
 * Created by zhq on 2016/6/23.
 */
public class IDCardModule extends SerialPortModule {

    public static final String TAG = "IDCardModule";
    private String serialDev = ConstDefine.ID_PORT;
    private int baudRate = 115200;
    private int GPIONUM = 206;
    private byte[] mBuffer = new byte[2320];
    private static IDCardModule ourInstance = new IDCardModule();

    //发送信息
    private final String sCmdReadSAMID = "AAAAAA9669000312FFEE";
    private final String sCmdFindCard = "AAAAAA96690003200122";
    private final String sCmdSelectCard = "AAAAAA96690003200221";
    private final String sCmdReadCardBase = "AAAAAA96690003300132";
    private final String sCmdReadNewAddress = "AAAAAA96690003300330";
    private final String sCmdReadCardFinger = "AAAAAA96690003301023";
    //命令返回信息
    private final String sFIND_NO_CARD = "AAAAAA9669000400008084";
    private final String sFIND_SUCC = "AAAAAA9669000800009F0000000097";
    private final String sREAD_NO_CARD = "AAAAAA9669000400004145";
    private final String sSELECT_NO_CARD = "AAAAAA9669000400008185";
    private final String sSELECT_SUCC = "AAAAAA9669000C00009000000000000000009C";


	private byte[] recvBuf = new byte[4096];
	
    public static IDCardModule getInstance() {
        return ourInstance;
    }

    protected boolean isOpen = false;

    private IDCardModule() {
        super();

    }
    public boolean init(){
        if (initSerialPort(this.serialDev, this.baudRate)) {
            Log.e("initserial", "open");
            isOpen = true;
            return true;
        }
        return false;
    }
    public boolean isOpen() {

        return isOpen;
    }

    public IdentityInfo317Bean ReadBaseCardInfo(String[] sRet) {
        if (!isOpen)
            return null;

        if (this.ReadCardBase(sRet)) {
            return decodeInfo(mBuffer, false, true);
        }
        return null;
    }

    public IdentityInfo317Bean ReadAllCardInfo(String[] sRet) {
        if (!isOpen) return null;
        String sNewAddress = "";
        if (ReadCardNewAddress(sRet)) {
            try {
                sNewAddress = new String(mBuffer, 3, 70, "UTF-16LE").trim();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        if (this.ReadCardFinger(sRet)) {
            IdentityInfo317Bean info = decodeInfo(mBuffer, true, true);
            if (info != null)
                info.setNewAddress(sNewAddress);
            return info;
        }
        return null;
    }


    public boolean FindCard(String[] sRet) {
        boolean bRet = SendAndRecv(sCmdFindCard, sRet, 500);
        if (!bRet) return false;
        if (sRet[0].equalsIgnoreCase(sFIND_SUCC)) return true;
        return false;
    }

    public boolean SelectCard(String[] sRet) {
        boolean bRet = SendAndRecv(sCmdSelectCard, sRet, 500);
        if (!bRet) return false;
        if (sRet[0].equalsIgnoreCase(sSELECT_SUCC)) return true;
        return false;
    }

    private boolean ReadCardBase(String[] sRet) {
        boolean bRet = SendAndRecv(sCmdReadCardBase, sRet, 5000);
        if (!bRet) return false;
        if (mBuffer[0] == (byte) 0x00 && mBuffer[1] == (byte) 0x00 && mBuffer[2] == (byte) 0x90)
            return true;
        return false;
    }

    private boolean ReadCardFinger(String[] sRet) {
        boolean bRet = SendAndRecv(sCmdReadCardFinger, sRet, 20000);
        if (!bRet) return false;
        if (mBuffer[0] == (byte) 0x00 && mBuffer[1] == (byte) 0x00 && mBuffer[2] == (byte) 0x90)
            return true;
        return false;
    }

    private boolean ReadCardNewAddress(String[] sRet) {
        boolean bRet = SendAndRecv(sCmdReadNewAddress, sRet, 1500);
        if (!bRet) return false;
        if (mBuffer[0] == (byte) 0x00 && mBuffer[1] == (byte) 0x00 && mBuffer[2] == (byte) 0x90)
            return true;
        return false;
    }


    private IdentityInfo317Bean decodeInfo(byte[] buffer, boolean haveFinger, boolean decodePhoto) {
        IdentityInfo317Bean people = new IdentityInfo317Bean();
        String temp = null;
        int nPtr = 3;
        short textSize = ByteTool.getShort(buffer[nPtr + 0], buffer[nPtr + 1]);
        short imageSize = ByteTool.getShort(buffer[nPtr + 2], buffer[nPtr + 3]);
        short fingerSize = 0;
        if (haveFinger) {
            fingerSize = ByteTool.getShort(buffer[nPtr + 4], buffer[nPtr + 5]);
            nPtr += 6;
        } else nPtr += 4;
        byte[] text = new byte[textSize];
        System.arraycopy(buffer, nPtr, text, 0, textSize);
        if (decodePhoto) {
            byte[] image = new byte[imageSize];
            System.arraycopy(buffer, nPtr + textSize, image, 0, imageSize);
            // people.setPhoto(parsePhoto(image));
            people.setIcon(WltLib.parsePhotoOther(image));
            people.setImageByte(image);
        }
        byte[] finger = null;
        if (fingerSize > 0) {
            finger = new byte[fingerSize];
            System.arraycopy(buffer, nPtr + textSize + imageSize, finger, 0, fingerSize);
            people.setFingerByte(finger);
        }
        try {


            temp = new String(text, 248, 2, "UTF-16LE").trim();//证件类型
            
            //Log.e("GJ", "证件类型"+temp);
            if(temp.equals("I")){

				String enName = new String(text, 0,
						120, "UTF-16LE").trim();

				String fprSex = new String(text,
						120, 2, "UTF-16LE").trim();

				String frpIDNo = new String(text,
						122, 30, "UTF-16LE").trim();

				String countryCode = new String(
						text, 152, 6, "UTF-16LE")
						.trim();

				String CHNName = new String(text,
						158, 30, "UTF-16LE").trim();

				String validStart = new String(
						text, 188, 16, "UTF-16LE")
						.trim();

				String validEnd = new String(text,
						204, 16, "UTF-16LE").trim();

				String Birthday = new String(text,
						220, 16, "UTF-16LE").trim();

				String idVer = new String(text,
						236, 4, "UTF-16LE").trim();

				String issuingAuthorityCode = new String(
						text, 240, 8, "UTF-16LE")
						.trim();
				 
				System.arraycopy(text, 256, recvBuf, 0, 1024);
				
//				bean.fullName = CHNName;
////				bean.icon = decodePhoto(recvBuf);
//	            people.setIcon(WltLib.parsePhotoOther(recvBuf));
//	            people.setImageByte(recvBuf);
//				bean.birthday = Birthday;
//				bean.idNo = frpIDNo;
//				bean.idOrg = issuingAuthorityCode;
//				bean.beginDate = validStart;
//				bean.endDate = validEnd;
//				// bean.idAddr = m_strAddress;
//				bean.countryCode= countryCode;
//				bean.nation = countryMap.get(countryCode);
//				bean.sex = findSexZW(Integer.valueOf(fprSex));
//				bean.cardType = "1";
//				bean.cardVer = idVer;
//				bean.enName = enName;
				
            }else if(temp.equals("J")){
            	
            	
            }else{
            	
            	people.setCardType("0");
                // 姓名
                temp = new String(text, 0, 30, "UTF-16LE").trim();
                people.setFullName(temp);
                // 性别
                temp = new String(text, 30, 2, "UTF-16LE");
                if (temp.equals("1"))
                    temp = "男";
                else
                    temp = "女";
                people.setSex(temp);
                // 民族
                temp = new String(text, 32, 4, "UTF-16LE");
                try {
                    int code = Integer.parseInt(temp.toString());
                    temp = parseNation(code);
                } catch (Exception e) {
                    temp = "";
                }
                people.setNation(temp);
                // 出生
                temp = new String(text, 36, 16, "UTF-16LE").trim();
                people.setBirthday(temp);
                // 住址
                temp = new String(text, 52, 70, "UTF-16LE").trim();
                people.setIdAddr(temp);
                // 身份证号
                temp = new String(text, 122, 36, "UTF-16LE").trim();
                people.setIdNo(temp);
                // 签发机关
                temp = new String(text, 158, 30, "UTF-16LE").trim();
                people.setIdOrg(temp);
                // 有效起始日期
                temp = new String(text, 188, 16, "UTF-16LE").trim();
                people.setBeginDate(temp);
                // 有效截止日期
                temp = new String(text, 204, 16, "UTF-16LE").trim();
                people.setEndDate(temp);
                
            }

        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
            return null;
        }
        return people;
    }

    public byte[] ReadSAMIDBuf(String[] sRet) {
        Log.i(TAG, "ReadSAMIDBuf()");
        boolean bRet = SendAndRecv(sCmdReadSAMID, sRet, 3000);
        if (!bRet) {
            Log.e(TAG, "ReadSAMIDBuf() SendAndRecv() error!");
            return null;
        }
        if (mBuffer[0] == (byte) 0x00 && mBuffer[1] == (byte) 0x00 && mBuffer[2] == (byte) 0x90) {
            byte[] tmp = new byte[16];
            System.arraycopy(mBuffer, 3, tmp, 0, tmp.length);
            Log.d(TAG, "ReadSAMIDBuf() tmp = " + tmp);
            return tmp;
        }
        Log.e(TAG, "ReadSAMIDBuf() error!");
        return null;
    }

    public String ReadSAMID(String[] sRet) {
        String sSAMID = "";
        boolean isTryOpen = false;
        try {
            if (!isOpen) {
                return null;
            }
            boolean bRet = SendAndRecv(sCmdReadSAMID, sRet, 300);
            if (!bRet) return sSAMID;
            if (mBuffer[0] == (byte) 0x00 && mBuffer[1] == (byte) 0x00 && mBuffer[2] == (byte) 0x90) {
                String temp1 = ByteTool.byteToHexString(mBuffer[3]);
                String temp2 = ByteTool.byteToHexString(mBuffer[5]);
                byte[] temp3 = new byte[4];
                System.arraycopy(mBuffer, 7, temp3, 0, temp3.length);
                ByteTool.reversal(temp3);
                byte[] temp4 = new byte[4];
                System.arraycopy(mBuffer, 11, temp4, 0, temp4.length);
                ByteTool.reversal(temp4);
                byte[] temp5 = new byte[4];
                System.arraycopy(mBuffer, 15, temp5, 0, temp5.length);
                ByteTool.reversal(temp5);
                StringBuffer sb = new StringBuffer();
                sb.append(temp1);
                sb.append(".");
                sb.append(temp2);
                sb.append("-");
                sb.append(ByteTool.byteArray2int(temp3));
                sb.append("-");
                String str4 = Long.toString(ByteTool.byteArray2int(temp4));
                for (int i = 0; i < 10 - str4.length(); i++) {
                    sb.append("0");
                }
                sb.append(str4);
                sb.append("-");
                String str5 = Long.toString(ByteTool.byteArray2int(temp5));
                for (int i = 0; i < 10 - str5.length(); i++) {
                    sb.append("0");
                }
                sb.append(str5);
                sSAMID = sb.toString();
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        } finally {
            if (isTryOpen) {
                isOpen = false;
                closeSerialPort();
            }
        }
        return sSAMID;
    }

    private boolean SendAndRecv(String sSendCmd, String[] sRecvResp, int nWaitTime) {
        int nLen = 0;
        if (!isOpen) return false;
        sRecvResp[0] = "";
        Arrays.fill(mBuffer, (byte) 0);
        byte[] bTmp;
        try {
            write(ByteTool.hexStr2Bytes(sSendCmd));
            Log.e("send:", sSendCmd);
            int nRet = receiveBytes(mBuffer, 7, nWaitTime);
            if (nRet != 7) {
                sRecvResp[0] = "read err1:" + String.valueOf(nRet);
                return false;
            }
            bTmp = new byte[7];
            System.arraycopy(mBuffer, 0, bTmp, 0, bTmp.length);
            sRecvResp[0] = ByteTool.byte2hex(bTmp);
            if (mBuffer[0] == (byte) 0xaa && mBuffer[1] == (byte) 0xaa && mBuffer[2] == (byte) 0xaa && mBuffer[3] == (byte) 0x96 && mBuffer[4] == (byte) 0x69) {
                nLen = ByteTool.getShort(mBuffer[5], mBuffer[6]);
                nRet = receiveBytes(mBuffer, nLen, nWaitTime);
                if (nRet != nLen) {
                    sRecvResp[0] = "read err2:" + String.valueOf(nRet);
                    return false;
                }
                bTmp = new byte[nLen];
                System.arraycopy(mBuffer, 0, bTmp, 0, bTmp.length);
                sRecvResp[0] += ByteTool.byte2hex(bTmp);
                Log.e("rev2:", sRecvResp[0]);
                return true;
            } else sRecvResp[0] = "read err3";
        } catch (IOException e) {
            e.printStackTrace();
            sRecvResp[0] = e.getMessage();
        }
        return false;
    }

    public void PowerOffReader()
    {
        FileUnits.WriteTxtFile("no", "/sys/devices/soc/10003000.keypad/elink_ledctrl");
    }

    public void PowerOnReader()
    {
        FileUnits.WriteTxtFile("en", "/sys/devices/soc/10003000.keypad/elink_ledctrl");
    }
//    public void PowerOnReader() {
//      //  GPIO.gpioCrtl(GPIONUM, 1);
//    }
//    public void PowerOffReader() {
//
//        //GPIO.gpioCrtl(GPIONUM, 0);
//    }

    public void ReleaseReader() {
        Log.i(TAG, "ReleaseReader()");
        isOpen = false;
        closeSerialPort();
       // ourInstance = null;

    }

    protected String parseNation(int code) {
        String nation;
        switch (code) {
            case 1:
                nation = "汉";
                break;
            case 2:
                nation = "蒙古";
                break;
            case 3:
                nation = "回";
                break;
            case 4:
                nation = "藏";
                break;
            case 5:
                nation = "维吾尔";
                break;
            case 6:
                nation = "苗";
                break;
            case 7:
                nation = "彝";
                break;
            case 8:
                nation = "壮";
                break;
            case 9:
                nation = "布依";
                break;
            case 10:
                nation = "朝鲜";
                break;
            case 11:
                nation = "满";
                break;
            case 12:
                nation = "侗";
                break;
            case 13:
                nation = "瑶";
                break;
            case 14:
                nation = "白";
                break;
            case 15:
                nation = "土家";
                break;
            case 16:
                nation = "哈尼";
                break;
            case 17:
                nation = "哈萨克";
                break;
            case 18:
                nation = "傣";
                break;
            case 19:
                nation = "黎";
                break;
            case 20:
                nation = "傈僳";
                break;
            case 21:
                nation = "佤";
                break;
            case 22:
                nation = "畲";
                break;
            case 23:
                nation = "高山";
                break;
            case 24:
                nation = "拉祜";
                break;
            case 25:
                nation = "水";
                break;
            case 26:
                nation = "东乡";
                break;
            case 27:
                nation = "纳西";
                break;
            case 28:
                nation = "景颇";
                break;
            case 29:
                nation = "柯尔克孜";
                break;
            case 30:
                nation = "土";
                break;
            case 31:
                nation = "达斡尔";
                break;
            case 32:
                nation = "仫佬";
                break;
            case 33:
                nation = "羌";
                break;
            case 34:
                nation = "布朗";
                break;
            case 35:
                nation = "撒拉";
                break;
            case 36:
                nation = "毛南";
                break;
            case 37:
                nation = "仡佬";
                break;
            case 38:
                nation = "锡伯";
                break;
            case 39:
                nation = "阿昌";
                break;
            case 40:
                nation = "普米";
                break;
            case 41:
                nation = "塔吉克";
                break;
            case 42:
                nation = "怒";
                break;
            case 43:
                nation = "乌孜别克";
                break;
            case 44:
                nation = "俄罗斯";
                break;
            case 45:
                nation = "鄂温克";
                break;
            case 46:
                nation = "德昂";
                break;
            case 47:
                nation = "保安";
                break;
            case 48:
                nation = "裕固";
                break;
            case 49:
                nation = "京";
                break;
            case 50:
                nation = "塔塔尔";
                break;
            case 51:
                nation = "独龙";
                break;
            case 52:
                nation = "鄂伦春";
                break;
            case 53:
                nation = "赫哲";
                break;
            case 54:
                nation = "门巴";
                break;
            case 55:
                nation = "珞巴";
                break;
            case 56:
                nation = "基诺";
                break;
            case 97:
                nation = "其他";
                break;
            case 98:
                nation = "外国血统中国籍人士";
                break;
            default:
                nation = "";
        }
        return nation;
    }

}
